package id;

import java.util.HashMap;

import org.bouncycastle.math.ec.ECPoint;

public class CertificateAuthority {

    private HashMap<CardAndSector, Certificate> sectorMap;

    protected CertificateAuthority() {
        this.sectorMap = new HashMap<CardAndSector, Certificate>();
    }

    private void addCardAndSector(CardAndSector cas, Certificate cert) {
        this.sectorMap.put(cas, cert);
    }

    public boolean verifyCertificate(Certificate cert) {
        Certificate c = this.sectorMap.get(new CardAndSector(cert.cardID, cert.sectorID));
        if (c.equals(cert)) {
            return true;
        }

        return false;
    }

    private boolean checkKey(String sectorID, Card card) {
        ZeroKnowledgeProof zkp = new ZeroKnowledgeProof(sectorID, card);
        return zkp.proof();
    }

    protected Certificate generateCertificate(Card card, String sectorID) throws Exception {
        if (this.checkKey(sectorID, card)) {
            Certificate cert = new Certificate(card.getSectorKey(sectorID), sectorID, card.getSectorUserID(sectorID),
                            String.valueOf(System.currentTimeMillis()));
            this.addCardAndSector(new CardAndSector(card.getSectorUserID(sectorID), sectorID), cert);
            return cert;
        } else {
            throw new Exception("Zero Knowledge Proof Failed!");
        }
    }

    class CardAndSector {
        String cardID;
        String sectorID;

        CardAndSector(String c, String s) {
            this.cardID = c;
            this.sectorID = s;
        }

        public boolean equals(CardAndSector cas) {
            if (!this.cardID.equals(cas.cardID)) {
                return false;
            }
            if (!this.sectorID.equals(cas.sectorID)) {
                return false;
            }

            return true;
        }
    }
}

class Certificate {

    ECPoint publicKey;
    String sectorID;
    String cardID;
    String timestamp;

    Certificate(ECPoint publicKey, String sectorID, String cardID, String timestamp) {
        this.publicKey = publicKey;
        this.sectorID = sectorID;
        this.cardID = cardID;
        this.timestamp = timestamp;
    }

    public boolean equals(Certificate cert) {

        if (!this.publicKey.equals(cert.publicKey)) {
            return false;
        }

        if (!this.sectorID.equals(cert.sectorID)) {
            return false;
        }

        if (!this.cardID.equals(cert.cardID)) {
            return false;
        }

        if (!this.timestamp.equals(cert.timestamp)) {
            return false;
        }

        return true;
    }
}
